Options

enum Option<T> {
    None,
    Some(T),
}
let some_number = Some(5);
let some_char = Some('e');

let absent_number: Option<i32> = None;

as_mut

  • The as_mut  method is a method of optional types , like Option<T> .

  • It is used to convert an Option<T>  into an Option<&mut T> . This allows accessing the contained value mutably without moving the value.

let mut opt: Option<String> = Some(String::from("Hello"));

if let Some(value) = opt.as_mut() {
    value.push_str(", world!"); // Modifies the contained value
}

println!("{:?}", opt); // Output: Some("Hello, world!")

Adapters for working with references

  • as_ref  converts from &Option<T>  to Option<&T> .

  • as_mut  converts from &mut Option<T>  to Option<&mut T> .

  • as_deref  converts from &Option<T>  to Option<&T::Target> .

  • as_deref_mut  converts from &mut Option<T>  to Option<&mut T::Target> .

  • as_pin_ref  converts from Pin<&Option<T>>  to Option<Pin<&T>> .

  • as_pin_mut  converts from Pin<&mut Option<T>>  to Option<Pin<&mut T>> .

Using ?

  • Without ? :

    fn add_last_numbers(stack: &mut Vec<i32>) -> Option<i32> {
        let a = stack.pop();
        let b = stack.pop();
    
        match (a, b) {
            (Some(x), Some(y)) => Some(x + y),
            _ => None,
        }
    }
    
    
  • With ? :

    fn add_last_numbers(stack: &mut Vec<i32>) -> Option<i32> {
        Some(stack.pop()? + stack.pop()?)
    }
    

Extracting the contained value

If let
let config_max = Some(3u8);
if let Some(max) = config_max {
    println!("The maximum is configured to be {max}");
}
Matching
fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

let five = Some(5);
let six = plus_one(five);
let none = plus_one(None);